/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package bygf.dts.device;

/**
 *
 * @author pi
 */

import bygf.dts.utility.CHexConver;
import java.util.List;

import javax.usb.UsbConfiguration;
import javax.usb.UsbDevice;
import javax.usb.UsbDeviceDescriptor;
import javax.usb.UsbEndpoint;
import javax.usb.UsbHostManager;
import javax.usb.UsbHub;
import javax.usb.UsbInterface;
import javax.usb.UsbPipe;
import javax.usb.event.UsbPipeDataEvent;
import javax.usb.event.UsbPipeErrorEvent;
import javax.usb.event.UsbPipeListener;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;


public class UsbUtil {
    private static Logger logger = LogManager.getLogger(UsbUtil.class.getName());
    private static final short idVendor = (short)0x154f;
    private static final short idProduct = (short)0x4401;
    private UsbPipe sendUsbPipe = null;
    private UsbPipe receivedUsbPipe = null;
    byte[] readBuf = new byte[100];

//    public static void test() {
//        try {
//            UsbPipe sendUsbPipe = new UsbUtil().useUsb();
//            
//            if (sendUsbPipe != null) {
//                byte[] buff = new byte[]{(byte)0xFE,0x00,0x02,0x0D,0x01,0x0C,(byte)0xEF};
//             
//                 sendMassge(sendUsbPipe, buff);
//                
//            }
//            
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
    
    public void openUsbPipe() throws Exception{
        UsbInterface iface = linkDevice();
        if (iface == null) {
            return;
        }
        UsbEndpoint receivedUsbEndpoint,sendUsbEndpoint;
        
        sendUsbEndpoint = (UsbEndpoint)iface.getUsbEndpoints().get(0);
        if (!sendUsbEndpoint.getUsbEndpointDescriptor().toString().contains("OUT")) {
            receivedUsbEndpoint = sendUsbEndpoint;
            sendUsbEndpoint = (UsbEndpoint)iface.getUsbEndpoints().get(1);
        } else {
            receivedUsbEndpoint = (UsbEndpoint)iface.getUsbEndpoints().get(1);
        }
        
        //发送：
        sendUsbPipe =  sendUsbEndpoint.getUsbPipe();
        sendUsbPipe.open();
        
        //接收
        receivedUsbPipe =  receivedUsbEndpoint.getUsbPipe();
        receivedUsbPipe.open();
//        receivedUsbPipe.addUsbPipeListener(new UsbPipeListener() {
//            @Override
//            public void errorEventOccurred(UsbPipeErrorEvent upee) {
//                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
//            }
//
//            @Override
//            public void dataEventOccurred(UsbPipeDataEvent upde) {
//                int rlen = upde.getActualLength();
//                upde.getUsbPipe().syncSubmit(readBuf);
//                //readBuf=upde.getData();
//                logger.debug("rlen = "+rlen+" Data= "+CHexConver.byte2HexStr(readBuf));
//                //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
//            }
//        });
        logger.debug("usb 成功打开");
        
        new Thread(new Runnable() {
            public void run() {
                try {
                    receivedMassge();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
//        return sendUsbPipe;
    }
    
    public UsbInterface linkDevice() throws Exception{

        UsbDevice device = null;
        if (device == null) {
             device = findDevice(UsbHostManager.getUsbServices()
                        .getRootUsbHub());
        }
        if (device == null) {
            System.out.println("设备未找到！");
            return null;
        }
        UsbConfiguration configuration = device.getActiveUsbConfiguration();
        UsbInterface iface = null;
        if (configuration.getUsbInterfaces().size() > 0) {
            iface = (UsbInterface)configuration.getUsbInterfaces().get(0);
        } else {
            return null;
        }
        iface.claim();
        return iface;
    }
    
    public void receivedMassge() throws Exception{
        byte[] b = new byte[64];
        int length = 0;
        while (true) {
            length = receivedUsbPipe.syncSubmit(b);//阻塞
            System.out.println("接收长度：" + length);
           
            System.out.print(CHexConver.byte2HexStr(b,length));
            
        }
    }
    
    public void sendMassge(byte[] buff){
        if (null != sendUsbPipe) {
            try {
                sendUsbPipe.syncSubmit(buff);//阻塞
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        }
        
        //usbPipe.asyncSubmit(buff);//非阻塞
    }
    public void closeUsbPipe(){
        if(null != sendUsbPipe&&sendUsbPipe.isOpen()){
           
            try {
                sendUsbPipe.close();
            } catch (Exception e) {
                e.printStackTrace();
            } 
             sendUsbPipe = null;
        }
        
        if(null != receivedUsbPipe&&receivedUsbPipe.isOpen()){
            
            try {
                receivedUsbPipe.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            receivedUsbPipe = null;
        }
    }
    public UsbDevice findDevice(UsbHub hub)
    {
        UsbDevice device = null;
        List list = (List) hub.getAttachedUsbDevices();
        for (int i = 0;i<list.size();i++)
        {
            device = (UsbDevice)list.get(i);
            UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor();
            if (desc.idVendor() == idVendor && desc.idProduct() == idProduct) {return device;}
            if (device.isUsbHub())
            {
                device = findDevice((UsbHub) device);
                if (device != null) return device;
            }
        }
        return null;
    }
    
    
    
    //    public void testUsb() {
//        // Create the libusb context
//        Context context = new Context();
//
//        // Initialize the libusb context
//        int result = LibUsb.init(context);
//        if (result < 0) {
//            throw new LibUsbException("Unable to initialize libusb", result);
//        }
//
//        // Read the USB device list
//        DeviceList list = new DeviceList();
//        result = LibUsb.getDeviceList(context, list);
//        if (result < 0) {
//            throw new LibUsbException("Unable to get device list", result);
//        }
//
//        try {
//            // Iterate over all devices and list them
//            for (Device device : list) {
//                int address = LibUsb.getDeviceAddress(device);
//                int busNumber = LibUsb.getBusNumber(device);
//                DeviceDescriptor descriptor = new DeviceDescriptor();
//                result = LibUsb.getDeviceDescriptor(device, descriptor);
//                if (result < 0) {
//                    throw new LibUsbException(
//                            "Unable to read device descriptor", result);
//                }
//                System.out.format(
//                        "Bus %03d, Device %03d: Vendor %04x, Product %04x%n",
//                        busNumber, address, descriptor.idVendor(),
//                        descriptor.idProduct());
//            }
//        } finally {
//            // Ensure the allocated device list is freed
//            LibUsb.freeDeviceList(list, true);
//        }
//
//        // Deinitialize the libusb context
//        LibUsb.exit(context);
//    }
}
